home *** CD-ROM | disk | FTP | other *** search
- /* store.c - storying files into (tape) archive
- * This is the part of the Tar program (see file tar.c)
- * Author: T.V.Shaporev
- * Creation date 14 Dec 1990
- */
- #include <stdio.h>
-
- #include "sysup.h"
- #include "nodedef.h"
- #include "modern.h"
- #include "define.h"
-
- char longname[] = "Tar: \'%s\' name too long%s";
-
- #ifdef unix
- # ifdef sun
- # ifndef STDDIR
- # define STDDIR
- # endif
- # include <dirent.h>
- # define DIRENT struct dirent
- # define namelen(d) strlen((d)->d_name)
- # endif
- # ifdef i386
- # ifndef STDDIR
- # define STDDIR
- # endif
- # include <dirent.h>
- # define DIRENT struct dirent
- # define namelen(d) strlen((d)->d_name)
- # else
- # ifdef M_XENIX
- # ifndef STDDIR
- # define STDDIR
- # endif
- # include <sys/ndir.h>
- # define DIRENT DIR
- # define namelen(d) ((d)->d_namlen)
- # endif
- # endif
- #endif
- #ifdef UNIX
- # ifndef STDDIR
- # include <sys/dir.h>
- # endif
- #endif
-
- #ifdef MSDOS
- # include <string.h>
- # ifdef __TURBOC__
- # include <dir.h>
- # else
- # include <direct.h>
- # endif
- # include <io.h>
- #else
- int strlen();
- char *strcpy(), *strcat(), *strncpy();
- int open(), read(), close();
- # ifdef RMKDIR
- int rmdir();
- # endif
- long lseek();
- #endif
-
- #define dotname(n) ((n)[0]=='.' && ((n)[1]=='\0'||((n)[1]=='.'&&(n)[2]=='\0')))
-
- void proctl __ARGS__(( char *, long ));
- void procts __ARGS__(( char *, short, char ));
- void prcsum __ARGS__(( register struct header * ));
- void newhead __ARGS__(( char *, long ));
- char *deleft __ARGS__(( char * ));
-
- void nullblock(h)
- struct header *h;
- {
- register i; for (i=0; i<BLKSIZE/sizeof(int); i++) *((int *)h + i) = 0;
- }
-
- void proctl(dest, l)
- char dest[]; long l;
- {
- register int i;
-
- dest[i = 11] = ' ';
- do dest[--i] = ((char)l & 7) | '0'; while (i>0 && (l>>=3)!=0);
- while (i>0) dest[--i] = ' ';
- }
-
- void procts(dest, s, suffix)
- char dest[]; short s; char suffix;
- {
- register int i;
-
- dest[7] = 0;
- dest[i = 6] = suffix;
- do dest[--i] = (s & 7) | '0'; while (i>0 && (s>>=3)!=0);
- while (i>0) dest[--i] = ' ';
- }
-
- void prcsum(h)
- register struct header *h;
- {
- register i;
- /* for the sake of compatibility */
- for (i=0; i<8; i++) (h->chksum)[i] = ' ';
- procts(h->chksum, headsum(h), 0);
- }
-
- void newhead(filename, filesize)
- char *filename;
- long filesize;
- {
- nullblock(hblock = steptape());
- procts(hblock->mode, (short)st.st_mode & 07777, ' ');
- procts(hblock->uid, (short)st.st_uid, ' ');
- procts(hblock->gid, (short)st.st_gid, ' ');
- proctl(hblock->size, filesize);
- proctl(hblock->mtime, st.st_mtime);
- (void)strncpy(hblock->name, filename, MAXTNAME);
- }
-
- char *deleft(p)
- register char *p;
- {
- #ifdef MSDOS
- if (deldrv && p[1] == ':' &&
- (p[0]>='A' && p[0]<='Z' || p[0]>='a' && p[0]<='z'))
- p += 2;
- #endif
- if (dslash && *p == '/') ++p;
- return p;
- }
-
- void store(fname)
- char *fname;
- {
- register i; register j;
- register unsigned m;
- static level = 0;
- #ifdef UNIX
- register char *p;
- # ifdef STDDIR
- register DIR *d0; register DIRENT *dp;
- # else
- register char *q; struct direct d_buf; int infile;
- # endif
- #endif
-
- #ifdef MSDOS
- register k;
- struct ffblk ff;
- #endif
-
- if (cbreak) done(0); ++level;
-
- if (strlen(fname) > MAXTNAME) {
- (void)fprintf(myout, longname, fname, "\n");
- goto end;
- }
- #ifdef MSDOS
- i = FALSE;
- for (j=strlen(fname); j>0 && fname[j-1]!='/' && fname[j-1]!=':'; j--) {
- if (fname[j-1]=='?' || fname[j-1]=='*') i = TRUE;
- }
-
- if (i) {
- k = findfirst(fname, &ff, filemask);
- while (k==0 && dotname(ff.ff_name)) k = findnext(&ff);
- if (k) {
- if (level < 2) (void)fprintf(myout,"Tar: can\'t find \'%s\'\n",fname);
- goto end;
- }
- do {
- takename(fname+j, ff.ff_name);
- store(fname);
- } while (findnext(&ff) == 0);
- goto end;
- }
- #endif
- if (stat(fname, &st) < 0) {
- (void)fprintf(myout, "Tar: can\'t handle \'%s\'\n", fname);
- goto end;
- }
- if ((m = st.st_mode & S_IFMT) == S_IFDIR) {
- if (nonest && level > 1) goto end;
-
- #ifdef UNIX
- if (p_flag) {/* save directory & permissions */
- newhead((p = deleft(fname)), 0L);
- if ((j = strlen(p)) < MAXTNAME-1) {
- hblock->name[j+1] = '\0';
- } else {
- j = MAXTNAME-1;
- }
- hblock->name[j] = '/';
- prcsum(hblock);
- }
- # ifdef STDDIR
- if ((d0 = opendir(fname)) == NULL) {
- (void)fprintf(myout, "Tar: can\'t open directory \'%s\'\n", fname);
- goto end;
- }
- fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
-
- for (dp=readdir(d0); dp; dp=readdir(d0)) {
- j = namelen(dp);
- if (j==0 ||
- (j==1 && (dp->d_name)[0]=='.') ||
- (j==2 && (dp->d_name)[0]=='.' && (dp->d_name[1])=='.'))
- continue;
- for (i=0; i<j; i++) p[i] = (dp->d_name)[i];
- p[j] = 0;
- store(fname);
- }
- closedir(d0);
- # else
- if ((infile = open(fname, O_RDONLY)) < 0) {
- (void)fprintf(myout, "Tar: can\'t open file \'%s\'\n", fname);
- goto end;
- }
- fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
-
- i = 0;
- while (read(infile, (char*)&d_buf, sizeof(d_buf)) > 0 && !cbreak) {
- if (d_buf.d_ino!=0 && !dotname(d_buf.d_name)) {
- q = p;
- for (j=0; j<DIRSIZ; j++) *q++ = d_buf.d_name[j];
- *q = '\0';
- (void)close(infile); /* need this file handler */
- store(fname);
- *p = '\0';
- infile = open(fname, O_RDONLY);
- (void)lseek(infile, (long)(sizeof(d_buf) * (i+1)), 0);
- }
- ++i;
- }
- # endif
- if (y_flag) {
- # ifdef RMKDIR
- if (rmdir(fname) != 0) {
- (void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
- }
- # else
- if (bincall("rmdir", fname) == -1) {
- (void)fprintf(myout, "Tar: fault run rmdir!\n");
- }
- # endif
- }
- #endif
- #ifdef MSDOS
- j = strlen(fname);
- strcpy(fname+j, "/*.*");
-
- store(fname);
-
- if (y_flag) {
- fname[j] = 0;
- if (rmdir(fname) != 0) {
- (void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
- }
- }
- #endif
- } else if (m == S_IFREG) {
- savefile(fname);
- } else {
- #ifdef UNIX
- p = deleft(fname);
- if (w_flag && !okwork('a', ' ', &st, fname)) goto end;
- if (v_flag) (void)fprintf(myout, "a %s\n", p);
- if (m == S_IFCHR || m == S_IFBLK || m == S_IFIFO) {
- newhead(p, 0L);
- if (m == S_IFIFO) {
- hblock->filetype = TF_QUE;
- } else {
- hblock->filetype = m == S_IFBLK ? TF_BLK : TF_CHR;
- procts(hblock->x.new.devmajor, major(st.st_rdev), ' ');
- procts(hblock->x.new.devminor, minor(st.st_rdev), ' ');
- }
- prcsum(hblock);
- } else
- #endif
- (void)fprintf(myout, "Tar: \'%s\' not a file\n", fname);
- }
- end: --level;
- }